Java JavaScript Python C# C C++ Go Kotlin PHP Swift R Ruby TypeScript Scala SQL Perl rust VisualBasic Matlab Julia

Python Functions → Concept of decorators

Python Functions

Concept of decorators

Python Functions and Decorators

Python functions are blocks of reusable code that perform specific tasks. They enhance code readability, modularity, and reusability. A function is defined using the `def` keyword, followed by the function name, parentheses containing parameters (optional), and a colon. The function body is indented.
Basic function example without decorator def greet(name): """This function greets the person passed in as a parameter.""" print(f"Hello, {name}!") greet("Sathish") # Output:

Output

Hello, Sathish!

Decorators: Enhancing Functions

Decorators are a powerful and expressive feature in Python that allows you to modify or enhance functions and methods in a clean and readable way. Essentially, a decorator is a function that takes another function as input and returns a modified version of that function. This modification happens *without* altering the original function's source code directly.

How Decorators Work

Decorators use the `@` symbol followed by the decorator function name, placed above the function definition. This is syntactic sugar; it's equivalent to assigning the decorated function to the result of the decorator function call.
python function with decorator example def my_decorator(func): def wrapper(): print("Something is happening before the function is called.") func() print("Something is happening after the function is called.") return wrapper @my_decorator def say_hello(): print("Hello!") say_hello()

Output

Something is happening before the function is called. Hello! Something is happening after the function is called.
In this example, `my_decorator` is the decorator. It takes `say_hello` as input, wraps it within the `wrapper` function (which adds extra functionality), and returns the `wrapper` function. The `@my_decorator` syntax makes the code concise and easy to read.

Multiple Decorators

You can apply multiple decorators to a single function. They are applied from top to bottom (innermost decorator is executed first).
Python function with Multiple Decorators example def bold_decorator(func): def wrapper(): return f"{func()}" return wrapper def italic_decorator(func): def wrapper(): return f"{func()}" return wrapper @bold_decorator @italic_decorator def greet(): return "Hello, world!" print(greet())

Output

Hello, world!

Decorators with Arguments

Decorators can also accept arguments. This requires a slightly more complex structure:
Decorators with Arguments def repeat(num_times): def decorator_repeat(func): def wrapper(*args, **kwargs): for _ in range(num_times): result = func(*args, **kwargs) return result return wrapper return decorator_repeat @repeat(num_times=3) def greet(name): print(f"Hello, {name}!") greet("Sathish")

Output

Hello, Sathish! Hello, Sathish! Hello, Sathish!
Here, `repeat` is a decorator factory – it creates and returns a decorator that takes `num_times` as an argument. The inner `decorator_repeat` function takes the function to be decorated (`func`), and the `wrapper` handles the actual repetition. `*args` and `**kwargs` allow the decorator to work with functions having any number of positional or keyword arguments.

Practical Applications

Decorators are useful for: Logging: Record function calls, arguments, and return values. Timing: Measure the execution time of a function. Authentication: Control access to functions based on user permissions. Caching: Store the results of expensive function calls to improve performance. Input validation: Check if function arguments are valid before execution. Important Note: When using decorators, it's crucial to preserve metadata (like docstrings and function names) using the `functools.wraps` decorator to avoid issues with introspection tools and documentation.
functools example import functools def my_decorator(func): @functools.wraps(func) # Preserves metadata def wrapper(): print("Before") func() print("After") return wrapper @my_decorator def say_hello(): """This is a simple function.""" print("Hello!") print(say_hello.__name__) print(say_hello.__doc__)

Output

say_hello This is a simple function.
By understanding decorators, you can write more elegant, reusable, and maintainable Python code. They are a powerful tool for extending the functionality of your functions without altering their core logic directly.

Tutorials